package com.linkwings.dbTemp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class HqlTool {

	public static Integer HQL_TYPE_SELECT = new Integer(0);
	public static Integer HQL_TYPE_COUNT = new Integer(1);
	public static Integer HQL_TYPE_SELECT_DISTINCT = new Integer(2);
	public static Integer HQL_TYPE_COUNT_DISTINCT = new Integer(3);

	public static String HQL_ORDER_TYPE_ASC = "";
	public static String HQL_ORDER_TYPE_DESC = "desc";

	private StringBuffer hql = new StringBuffer("");
	private List<Object> paramList = new ArrayList<Object>();


	public static HqlTool createDistinctSelectHql(String tableName){
		return new HqlTool(tableName, HqlTool.HQL_TYPE_SELECT_DISTINCT);
	}

	public static HqlTool createDistinctCountHql(String tableName){
		return new HqlTool(tableName, HqlTool.HQL_TYPE_COUNT_DISTINCT);
	}

	public static HqlTool createSelectHql(String tableName){
		return new HqlTool(tableName, HqlTool.HQL_TYPE_SELECT);
	}

	public static HqlTool createCountHql(String tableName){
		return new HqlTool(tableName, HqlTool.HQL_TYPE_COUNT);
	}

	public static HqlTool createMaxHql(String tableName, String fieldName){
		HqlTool tool = new HqlTool();
		tool.makeMaxSelectModel(tableName, fieldName);
		return tool;
	}

	public static HqlTool createMixHql(String tableName, String fieldName){
		HqlTool tool = new HqlTool();
		tool.makeMinSelectModel(tableName, fieldName);
		return tool;
	}

	public static HqlTool createUpdateHql(String tableName, Map<String, Object> map){
		HqlTool tool = new HqlTool();
		tool.makeUpdateModel(tableName, map);
		return tool;
	}

	public static HqlTool createUpdateHql(String tableName, String fieldName, Object value){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(fieldName, value);

		HqlTool tool = new HqlTool();
		tool.makeUpdateModel(tableName, map);
		return tool;
	}

	public static HqlTool createDeleteHql(String tableName){
		HqlTool tool = new HqlTool();
		tool.hql.append(" delete from " + tableName  + " o where 1=1 ");
		return tool;
	}

	public HqlTool(){
	}

	public HqlTool(String tableName, Integer type){
		if(HqlTool.HQL_TYPE_SELECT.equals(type)){
			this.hql.append(" from " + tableName + " o where 1=1");
		}else if(HqlTool.HQL_TYPE_COUNT.equals(type)){
			this.hql.append(" select count(o) from " + tableName + " o where 1=1");
		}else if(HqlTool.HQL_TYPE_SELECT_DISTINCT.equals(type)){
			this.hql.append(" select distinct(o)  from " + tableName + " o where 1=1");
		}else if(HqlTool.HQL_TYPE_COUNT_DISTINCT.equals(type)){
			this.hql.append(" select count(distinct(o)) from " + tableName + " o where 1=1");
		}
	}

	public void makeMaxSelectModel(String tableName, String fieldName){
		this.hql.append(" select max(o." + fieldName + ") from " + tableName + " o where 1=1");
	}


	public void makeMinSelectModel(String tableName, String fieldName){
		this.hql.append(" select min(o." + fieldName + ") from " + tableName + " o where 1=1");
	}

	public void makeUpdateModel(String tableName, Map<String, Object> map){
		this.hql.append(" update " + tableName + " o ");
		Set<String> keySet = map.keySet();
		StringBuffer str = new StringBuffer("");
		for(String key : keySet){
			if(!str.toString().equals("")){
				str.append(",");
			}
			Object value = map.get(key);
			str.append(" set o." + key + "=? ");
			this.paramList.add(value);
		}

		this.hql.append(str.toString());

		this.hql.append(" where 1=1 ");
	}


	public void addLikeCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + " like (?) ");
			this.paramList.add("%" + value + "%");
		}
	}

	public void addEqualCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + "=? ");
			this.paramList.add(value);
		}
	}


	public void addOrCondition(List<HqlConditionBean> list){
		StringBuffer str = new StringBuffer("");
		boolean flag = false;

		for(HqlConditionBean condition : list){
			String key = condition.getField();
			Object value = condition.getValue();
			if(value!=null && !"".equals(value)){
				flag = true;
				if(!str.toString().equals("")){
					str.append(" or ");
				}
				str.append(" o." + key + "=? ");
				this.paramList.add(value);
			}
		}

		if(flag){
			String s = " and (" + str.toString() + " ) ";
			this.hql.append(s);
		}
	}


	public void addOrLikeCondition(List<HqlConditionBean> list){
		StringBuffer str = new StringBuffer("");
		boolean flag = false;
		for(HqlConditionBean condition : list){
			String key = condition.getField();
			Object value = condition.getValue();
			if(value!=null && !"".equals(value)){
				flag = true;
				if(!str.toString().equals("")){
					str.append(" or ");
				}
				str.append(" o." + key + " like ? ");
				this.paramList.add("%" + value + "%");
			}
		}

		if(flag){
			String s = " and (" + str.toString() + " ) ";
			this.hql.append(s);
		}
	}

	public void addBetweenCondition(String fieldName, Object startValue, Object endValue){
		if(startValue!=null && !"".equals(startValue) && endValue!=null && !"".equals(endValue)){
			this.hql.append(" and o." + fieldName + " between ? and ? ");
			this.paramList.add(startValue);
			this.paramList.add(endValue);
		}else if(startValue!=null && !"".equals(startValue)){
			this.addBiggerNEqualCondition(fieldName, startValue);
		}else if(endValue!=null && !"".equals(endValue)){
			this.addSmallerNEqualCondition(fieldName, endValue);
		}
	}

	public void addInCondition(String fieldName, List valueList){

		if(valueList!=null && valueList.size()>0){
			this.hql.append(" and o." + fieldName + " in ( ");
			StringBuffer str = new StringBuffer("");
			for(Object object : valueList){
				if(!str.toString().equals("")){
					str.append(",");
				}
				str.append("?");
				this.paramList.add(object);
			}
			this.hql.append(str.toString());
			this.hql.append(" ) ");
		}
	}

	public void addNotEqualCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + "<>? ");
			this.paramList.add(value);
		}
	}

	public void addBiggerCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + ">? ");
			this.paramList.add(value);
		}
	}

	public void addBiggerNEqualCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + ">=? ");
			this.paramList.add(value);
		}
	}

	public void addSmallerCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + "<? ");
			this.paramList.add(value);
		}
	}

	public void addSmallerNEqualCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and o." + fieldName + "<=? ");
			this.paramList.add(value);
		}
	}

	public void addAnyElementsCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and ? = any elements(o." + fieldName + ") ");
			this.paramList.add(value);
		}
	}


	public void addSomeElementsCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and ? = some elements(o." + fieldName + ") ");
			this.paramList.add(value);
		}
	}

	public void addExistsElementsCondition(String fieldName, Object value){
		if(value!=null && !"".equals(value)){
			this.hql.append(" and ? = exists elements(o." + fieldName + ") ");
			this.paramList.add(value);
		}
	}



	public void addOrderBy(String field, String direction){
		List<String> fieldList = new ArrayList<String>();
		fieldList.add(field);
		List<String> directionList = new ArrayList<String>();
		directionList.add(direction);

		this.addOrderBy(fieldList, directionList);
	}

	public void addOrderByList(String field, List list){
		if(list!=null && list.size()>0){
			this.hql.append(" order by ");
			StringBuffer str = new StringBuffer("");
			for(Object obj : list){
				if(!str.toString().equals("")){
					str.append(",");
				}
				str.append(" o." + field + "=? desc ");
				this.paramList.add(obj);
			}
			this.hql.append(str.toString());
		}
	}

	public void addOrderBy(List<String> fieldList, List<String> directionList){
		if(fieldList!=null && fieldList.size()>0){
			this.hql.append(" order by ");
			StringBuffer str = new StringBuffer("");
			for(int i=0;i<fieldList.size();i++){
				if(!str.toString().equals("")){
					str.append(",");
				}
				str.append(" o." + fieldList.get(i) + " " + directionList.get(i));
			}
			this.hql.append(str.toString());
		}
	}

	public void addOrderByRand(){
		this.hql.append(" order by rand() ");
	}

	public void addGroupBy(String fieldName){
		if(fieldName!=null && !"".equals(fieldName)){
			this.hql.append(" group by o." + fieldName + " ");
		}
	}

	public void addGroupBy(List<String> fieldNameList){
		if(fieldNameList!=null && fieldNameList.size()>0){
			this.hql.append(" group by ");
			for(String fieldName : fieldNameList){
				if(fieldNameList.indexOf(fieldName)>0){
					this.hql.append(" , ");
				}
				this.hql.append(" o." + fieldName);
			}
		}
	}

	public void addEqualNullCondition(String fieldName){
		this.hql.append(" and o." + fieldName + " is null ");
	}

	public void addEqualNotNullCondition(String fieldName){
		this.hql.append(" and o." + fieldName + " is not null ");
	}


  public StringBuffer getHql() {
  	return hql;
  }


  public void setHql(StringBuffer hql) {
  	this.hql = hql;
  }


  public List<Object> getParamList() {
  	return paramList;
  }


  public void setParamList(List<Object> paramList) {
  	this.paramList = paramList;
  }

  public static boolean canBuildCondition(Object obj){
	  if(obj == null){
		return Boolean.FALSE;
	  }
	 if("".equals(String.valueOf(obj))){
		 return Boolean.FALSE;
	 }
	return Boolean.TRUE;
  }
}
